package com.jplus.core.plugin.transaction;

import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jplus.core.anno.boot.Configuration;
import com.jplus.core.core.proxys.Proxy;
import com.jplus.core.core.proxys.ProxyChain;
import com.jplus.core.db.TransactionManager;

/**
 * 【核心插件】事务拦截、基于插件<br>
 * 使用方式：在需要事务的类上或方法上 添加注解：@Transaction 即可
 */
@Configuration
public class TransactionConfigurationProxy implements Proxy {
	private final Logger logger = LoggerFactory.getLogger(TransactionConfigurationProxy.class);

	@Override
	public final Object doProxy(ProxyChain proxyChain) throws Throwable {
		Object result;
		// 判断当前线程是否进行了事务处理
		boolean flag = TransactionManager.isTransaction();// 事务传播性
		// 获取目标方法
		Method method = proxyChain.getTargetMethod();
		Transaction trans = proxyChain.getTargetClass().getAnnotation(Transaction.class);
		if (trans == null)
			trans = method.getAnnotation(Transaction.class);
		// 若当前线程未进行事务处理，且在目标方法上定义了 Transaction 注解，则说明该方法需要进行事务处理
		if (!flag && trans != null) {
			// 设置当前线程已进行事务处理
			TransactionManager.openTransaction();
			try {
				int level = trans.level();
				// 开启事务
				TransactionManager.openTransaction(level);
				logger.info("[DB] begin transaction");
				// 执行目标方法
				result = proxyChain.doProxyChain();
				// 提交事务
				TransactionManager.commitTransaction();
				logger.info("[DB] commit transaction");
			} catch (Exception e) {
				// 回滚事务
				TransactionManager.rollbackTransaction();
				logger.info("[DB] rollback transaction");
				throw e;
			}
		} else {
			// 执行目标方法
			result = proxyChain.doProxyChain();
		}
		return result;
	}
}
